<?php

/**
 * 安心站长axzz.cn，一个追求技术创造者。让网站、小程序、APP、应用程序牛起来……
 *
 * cighsen02 qq 365182575
 * 
 * Create at: 2022.05.26
 * Update at: 2025.11.24
 */

namespace Twoir\System\Support;

use function array_values;
use function array_filter;
use function array_keys;
use function count;
use function implode;
use function is_array;
use function preg_match;
use function str_contains;
use function strtoupper;

/**
 * 构造语句前置处理
 */
trait ParseTrait
{
    const REGEX = [
        'where'     => '/(\w+)\s+(>=|<=|!=|>|<|in|like)/i',
        'update'    => '/\w+\s+(\+|-)\s+(\d+)/'
    ];

    /**
     * 简单数组转字符串, 给值增加""，
     *
     * @param array $data
     * @return string
     */
    private static function value2String(array $data, string $type = 'string'): string
    {
        foreach($data as &$item) {

            if ('string' === $type) $item = "'" . $item . "'";
        }

        return implode(',', $data);
    }

    /**
     * 询查构造
     *
     * @param array $where
     * @return array;
     */
    public static function parseWhere(array $where = []): array
    {
        if (empty($where)) return ['', []];

        $field  = static::fieldType();
        $str 	= '';
        $data   = [];
        foreach((array)$where as $key => $value) {

            // 去除null值
            if (null !== $value) {

                // 默认
                $eq = ' = ';
                // 增加空判断可以加快
                if (str_contains($key, ' ') && preg_match(static::REGEX['where'], $key, $matches)) {
                    // 真正key
                    $key = $matches[1];
                    // in处理
                    if ('in' === $matches[2] && is_array($value)) {

                        $value = array_values($value);
                        if (count($value) > 1) {

                            $type   = isset($field[$key]) && $field[$key] ? $field[$key] : 'string';
                            $eq     = 'IN';
                            $value  = '(' . static::value2String($value, $type) . ')';
                        }
                        else {

                            $value = $value[0];
                        }
                    }
                    else {

                        $eq = strtoupper($matches[2]);
                    }
                }
                // 值的类型处理,字符串时
                if (!isset($field[$key]) || ('string' === $field[$key] && !in_array($eq, ['IN','>=','<=','!=','>','<']))) $value = "'" . $value . "'";

                $data[$key] = $value;
                $str .= ($str ? ' AND ' : '') . '`' . $key . '`' . $eq . $value;
            }
        }

        return [
            $str ? ' WHERE ' . $str : '',
            $data
        ];
    }

    /**
     * 构造插入语句
     *
     * @param array $data
     * @return array
     */
    public static function parseInsert(array $data): array
    {
        if (empty($data)) return ['key' => '', 'value' => ''];
        // 去null值
        $data   = array_filter($data, fn($item) => null !== $item);
        $field  = static::fieldType();

        foreach($data as $key => &$value) {

            $value = !isset($field[$key]) || 'string' === $field[$key] ? "'" . $value . "'" : $value;
        }

        return ['`'. implode('`,`', array_keys($data)) . '`', implode(',', array_values($data))];
    }

    /**
     * 构造更新语句
     *
     * @param array $add
     * @return string
     */
    public static function parseUpdate(array $add): string
    {
        // 去null值
        $add    = array_filter((array)$add, fn($item) => null !== $item);
        $field  = static::fieldType();
        $str    = '';
        foreach($add as $key => $value) {

            if (1 === preg_match(static::REGEX['update'], $value)) {

                $str .= ($str ? ',' : '') . '`' . $key . '` = ' . str_replace($key, '`' . $key . '`', $value);
            }
            elseif (!isset($field[$key]) || 'string' === $field[$key]) {

                $str .= ($str ? ',' : '') . '`' . $key . '` = ' . "'" . $value . "'";
            }
            else {

                $str .= ($str ? ',' : '') . '`' . $key . '` = ' . (int)$value;
            }
        }

        return $str;
    }

    /**
     * mysql置后开启
     * 
     * @return void
     */
    public static function enableLowPriority()
    {
        static::$low_priority = true;
    }

    /**
     * mysql置后关闭
     * 
     * @return void
     */
    public static function disableLowPriority()
    {
        static::$low_priority = false;
    }
}
